#include "widget.h"
#include "ui_widget.h"

#include <QMouseEvent>
#include <QDebug>
#include <QNetworkAccessManager>
#include <QMessageBox>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //初始化界面
    initialization();
    //初始化http链接
    InitializHTTPLink();
    //初始化ui控件，放入QList集中管理
    InitializeUiData();

    //为六日高温和低温界面安装事件过滤器
    ui->widget04_04->installEventFilter(this);
    ui->widget04_05->installEventFilter(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::initialization()
{
    this->setFont(QFont("Arial",15));
    setFixedSize(530,879);
    //无边框
    setWindowFlag(Qt::FramelessWindowHint);

    menuQuit = new QMenu(this);
    //设置菜单文字颜色
    menuQuit->setStyleSheet("QMenu::item {color : white}");
    //为menu添加选项
    QAction *openAct = new QAction(QIcon(":/Iron/close.png"), tr("退出"), this);
    menuQuit->addAction(openAct);

    connect(menuQuit,&QMenu::triggered,this,[=](){
        this->close();
    });
}

void Widget::InitializHTTPLink()
{
    //由NetworkAccessManager发起get请求
    manager = new QNetworkAccessManager(this);
    //指定url地址
    strUrl = "http://gfeljm.tianqiapi.com/api?unescape=1&version=v9&appid=92525161&appsecret=3PiKwsBf";
    QUrl urlWeather(strUrl);
    QNetworkRequest res(urlWeather);
    reply = manager->get(res);
    //网络请求后进行数据读取
    connect(manager,&QNetworkAccessManager::finished,this,&Widget::readHttpReply);
}

void Widget::InitializeUiData()
{
    mDateList << ui->labelDate0  << ui->labelDate1
              << ui->labelDate2<< ui->labelDate3
              << ui->labelDate4<< ui->labelDate5;

    mWeekList << ui->labelDay0 << ui->labelDay1
              << ui->labelDay2<< ui->labelDay3
              << ui->labelDay4<< ui->labelDay5;

    mIconList << ui->labelWeathIcon0<< ui->labelWeathIcon1
              << ui->labelWeathIcon2<< ui->labelWeathIcon3
              << ui->labelWeathIcon4<< ui->labelWeathIcon5;

    mWeaTypeList<<ui->labelWeatherType0<<ui->labelWeatherType1
               <<ui->labelWeatherType2<<ui->labelWeatherType3
              <<ui->labelWeatherType4<<ui->labelWeatherType5;

    mAirqList<<ui->labelAirQ0<<ui->labelAirQ1
            <<ui->labelAirQ2<<ui->labelAirQ3
           <<ui->labelAirQ4<<ui->labelAirQ5;

    mFxList<<ui->labelWind0<<ui->labelWind1
          <<ui->labelWind2<<ui->labelWind3
         <<ui->labelWind4<<ui->labelWind5;

    mFlList<<ui->labelWindLevl00<<ui->labelWindLevl01
          <<ui->labelWindLevl02<<ui->labelWindLevl03
         <<ui->labelWindLevl04<<ui->labelWindLevl05;

    //设置icon路径
    mTypeMap.insert("雪",":/Iron/xue.png");
    mTypeMap.insert("雷",":/Iron/lei.png");
    mTypeMap.insert("沙尘",":/Iron/shachen.png");
    mTypeMap.insert("雾",":/Iron/wu.png");
    mTypeMap.insert("冰雹",":/Iron/bingbao.png");
    mTypeMap.insert("云",":/Iron/yun.png");
    mTypeMap.insert("雨",":/Iron/yu.png");
    mTypeMap.insert("阴",":/Iron/yintian.png");
    mTypeMap.insert("晴",":/Iron/clearDay.png");
}

//装载基于易天气的专业七日天气v9的JSON数据到本地
void Widget::NewparseWeatherJsonData(QByteArray rawData)
{
    QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
    if(!jsonDoc.isNull() && jsonDoc.isObject())
    {
        QJsonObject jsonRoot = jsonDoc.object();
        days[0].mCity = jsonRoot["city"].toString();
        days[0].mPm25 = jsonRoot["aqi"].toObject()["pm25"].toString();
        if(jsonRoot.contains("data")&&jsonRoot["data"].isArray())
        {
            QJsonArray weaArray = jsonRoot["data"].toArray();
            for(int i=0;i<weaArray.size();i++)
            {
                QJsonObject dayObject = weaArray[i].toObject();
                //qDebug() << dayObject["date"].toString() << dayObject["day"];
                days[i].mDate = dayObject["date"].toString();
                days[i].mWeek = dayObject["week"].toString();
                days[i].mWeatherType = dayObject["wea"].toString();
                days[i].mTemp = dayObject["tem"].toString();
                days[i].mTempLow = dayObject["tem2"].toString();
                days[i].mTempHigh = dayObject["tem1"].toString();
                days[i].mShidu = dayObject["humidity"].toString();
                days[i].mFx = dayObject["win"].toArray()[0].toString();
                days[i].mFl = dayObject["win_speed"].toString();
                days[i].mAirq = dayObject["air_level"].toString();
                days[i].mTips = dayObject["air_tips"].toString();
            }
        }
    }
    updateUI();
}

//当manager的finished信号触发时，获取链接状态，通信正常则申请JSON数据
void Widget::readHttpReply(QNetworkReply *reply)
{
    //获取状态码
    int resCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    qDebug() <<resCode;
    if(reply->error() == QNetworkReply::NoError && resCode == 200)
    {
        //大多服务器返回的字符编码为utf-8
        QByteArray data = reply->readAll();
        NewparseWeatherJsonData(data);
        //qDebug() << QString::fromUtf8(data);
    }
    else
    {
        QMessageBox msg;
        msg.setWindowTitle("错误");
        msg.setText("网络请求失败！");
        msg.setStyleSheet("QPushButton {color:black}");
        msg.setStandardButtons(QMessageBox::Ok);
        msg.exec();
    }
}

//事件过滤器捕获画图事件
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if((watched == ui->widget04_04 || watched == ui->widget04_05) && event->type() == QEvent::Paint)
    {
        bool isHigh = (watched == ui->widget04_04);
        drawTempLine(isHigh);
    }

    return QWidget::eventFilter(watched,event);
}

//绘制高温线和低温线
void Widget::drawTempLine(bool isHigh)
{
    QWidget* target = isHigh ? ui->widget04_04 : ui->widget04_05;
    QColor color = isHigh ? QColor(234, 156, 0) : QColor(93, 212, 230);

    QPainter painter(target);
    painter.setPen(color);
    painter.setBrush(color);
    painter.setRenderHints(QPainter::Antialiasing |
                          QPainter::TextAntialiasing |
                          QPainter::SmoothPixmapTransform);

    //定义6天的高温点
    int sum = 0;
    for(int i = 0;i<6;++i)
    {
        //根据温度不同分别得出六日高温和低温的总和
        const QString& temp = isHigh ? days[i].mTempHigh : days[i].mTempLow;
        sum += temp.toInt();
    }
    int avg = sum/6;
    //控件中间位置，即中间值
    const int middleY = target->height()/2;
    QPoint point[6];
    for(int i=0;i<6;++i)
    {
        const QString& temp = isHigh ? days[i].mTempHigh : days[i].mTempLow;
        //偏移值=当天温度-平均温度
        int offset = temp.toInt() - avg;
        //根据空气质量控件位置作为基准
        point[i].setX(mAirqList[i]->x()+mAirqList[i]->width()/2);
        point[i].setY(middleY - offset*3);
        painter.drawEllipse(QPoint(point[i]),2,2);
        //画温度
        painter.drawText(point[i].x()-10,point[i].y()-10,days[i].mTempHigh+"°");
    }

    //画线
    for(int i=0;i<5;i++)
    {
        painter.drawLine(point[i],point[i+1]);
    }
}

//根据天气类型选择图标(上层)
void Widget::ChangeUpperWeatherIcon(QString str)
{
    for(auto it = mTypeMap.begin();it!=mTypeMap.end();it++)
    {
        //遍历map并判断天气类型字符中是否有匹配图标
        if(str.contains(it.key()))
        {
            ui->labelWeatherIcon->setPixmap(it.value());
        }
    }
    return;
}

//根据天气类型选择图标(下层)
void Widget::ChangeDownWeatherIcon(QString str,int i)
{
    for(auto it = mTypeMap.begin();it!=mTypeMap.end();it++)
    {
        //遍历map并判断天气类型字符中是否有匹配图标
        if(str.contains(it.key()))
        {
            mIconList[i]->setPixmap(it.value());
        }
    }
    return;
}

//将已装载好的数据更新到UI界面中
void Widget::updateUI()
{

    //解析日期
    ui->labelCurrentDate->setText(days[0].mDate + " " + days[0].mWeek);
    //解析城市名称
    ui->labelCity->setText(days[0].mCity);
    //解析当前温度
    ui->labelMainTemperature->setText(days[0].mTemp+"℃");
    ui->labelTemperRange->setText(days[0].mTempLow+"~"+days[0].mTempHigh+"℃");
    //解析天气类型
    ui->labelWeatherType->setText(days[0].mWeatherType);
    //根据天气类型更换上层天气图标
    ChangeUpperWeatherIcon(days[0].mWeatherType);

    //感冒指数
    ui->labelGanMao->setText("Tips:" + days[0].mTips);
    //风向
    ui->labelFXType->setText(days[0].mFx);
    //风力
    ui->labelFXData->setText(days[0].mFl);
    //湿度
    ui->labelShiDuData->setText(days[0].mShidu);
    //PM2.5
    ui->labelPM25Data->setText(days[0].mPm25);
    //空气质量
    ui->labelAirData->setText(days[0].mAirq);

    for(int i=0;i<6;i++)
    {
        QStringList strList =  days[i].mDate.split("-");//xxxx-xx-xx
        mDateList[i]->setText(strList[1] + "/"+strList[2]);//xx/xx
        if(i>=2)
            mWeekList[i]->setText(days[i].mWeek);
        ChangeDownWeatherIcon(days[i].mWeatherType,i);
        mWeaTypeList[i]->setText(days[i].mWeatherType);
        mAirqList[i]->setText(days[i].mAirq);
        QString airQ = days[i].mAirq;
        if(airQ == "优")
            mAirqList[i]->setStyleSheet("background-color: rgb(150, 213,32);border-radius: 6px;");//绿色
        if(airQ =="良")
            mAirqList[i]->setStyleSheet("background-color: rgb(255, 202, 7);border-radius: 6px;");//橙色
        if(airQ =="轻度污染")
            mAirqList[i]->setStyleSheet("background-color: rgb(255, 200, 200);border-radius: 6px;");
        if(airQ =="中度污染")
            mAirqList[i]->setStyleSheet("background-color: rgb(255, 0, 0);border-radius: 6px;");
        if(airQ =="重度污染")
            mAirqList[i]->setStyleSheet("background-color: rgb(178, 34, 34);border-radius: 6px;");
        if(airQ =="严重污染")
            mAirqList[i]->setStyleSheet("background-color: rgb(101, 0, 0);border-radius: 6px;");

        if(days[i].mFx == "无持续风向")
        {
            mFxList[i]->setText("无风向");
        }
        else
        {
            mFxList[i]->setText(days[i].mFx);
        }
        mFlList[i]->setText(days[i].mFl);
    }

    update();
}

//当搜索按钮被按下
void Widget::on_pushButton_clicked()
{
    //请求资源前先释放资源
    if(reply && reply->isRunning()) {
        reply->abort();
        reply->deleteLater();
    }
    QString cityNameFormUser = ui->lineEditCity->text();
    QString cityCode = cityCoudeUtils.getCityCoudeFromName(cityNameFormUser);

    if(cityCode!=NULL)
    {
        strUrl += "&cityid=" + cityCode;
        manager->get(QNetworkRequest(QUrl(strUrl)));

    }
    else
    {
        QMessageBox msg;
        msg.setWindowTitle("错误");
        msg.setText("请输入正确的城市名称");
        msg.setStyleSheet("QPushButton {color:black}");
        msg.setStandardButtons(QMessageBox::Ok);
        msg.exec();
    }
}

//当用户在城市搜索栏输入回车
void Widget::on_lineEditCity_returnPressed()
{
    on_pushButton_clicked();
}

//鼠标右击界面事件，弹出退出按钮
void Widget::mousePressEvent(QMouseEvent *event)
{
    //右键弹出菜单
    if(event->button() == Qt::RightButton)
    {
        //qDebug() <<"Right Mous clicked";
        //在鼠标当前位置展开
        menuQuit->exec(QCursor::pos());
    }
    //左键持续按下拖动窗口
    //鼠标当前位置（于整个屏幕）:event->globalPos();
    //窗口当前位置:this->pos();
    if(event->button() == Qt::LeftButton)
    {
        //qDebug() << event->globalPos() << this->pos();
        //计算窗口左上角位置与鼠标当前位置偏移值
        //event->pos().x() = event->globalX() - this->pos().x()
        Offset =event->pos();
    }
}

//鼠标移动事件，实现拖动窗口功能
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    //移动窗口
    this->move(event->globalPos() - Offset);
}


